package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"gitee.com/thewalkers/refactoring-code/logger"
	"gitee.com/thewalkers/refactoring-code/settings"
	"go.uber.org/zap"
)

func main() {
	log.Println("Server start...")

	// 1. 初始化配置
	if err := settings.Init(); err != nil {
		log.Printf("init settings failed, err: %v\n", err)
		return
	}

	// 2. 初始化日志
	if err := logger.Init(settings.Config.LogConfig); err != nil {
		fmt.Printf("init logger failed, err: %v\n", err)
		return
	}
	defer zap.L().Sync()
	zap.L().Debug("logger init success ...")

	// 3. mysql 数据库初始化
	ds, err := initDS(settings.Config.MySQLConfig)
	if err != nil {
		log.Fatalf("Unable to initialize data sources: %v\n", err)
		return
	}
	defer ds.close()

	// 4. 路由初始化
	router, err := inject(ds)
	if err != nil {
		log.Fatalf("Unable to inject data sources: %v\n", err)
		return
	}

	server := &http.Server{
		Addr:    fmt.Sprintf(":%d", settings.Config.Port),
		Handler: router,
	}

	go func() {
		// 开启一个 goroutine 启动服务
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %s", err.Error())
		}
	}()

	// 平滑关闭服务
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := server.Shutdown(ctx); err != nil {
		zap.L().Fatal("Server Shutdown: ", zap.Error(err))
	}

	zap.L().Info("Server exiting")
}
